package mobilesmil.data;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

import mobilesmil.utils.ColorUtils;

import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.Paint.Align;

/**
 * The resource Object that extends {@link SmilResource} and provides functionality for
 * playing text in a SMIL. The text will be justified center with positioning of the text
 * starting at the top of the region continuing downward until the end of text or the end
 * of its region.
 */
public class SmilTextResource extends SmilResource {
	/**
	 * String set to the text from the source.
	 */
	protected String mText;
	private String[] mBreakText;
	private int mX, mY;
	private Paint mTextColor;
	
	/**
	 * 
	 * @param source		Name of .txt file where the text to be used is.
	 * @param smilRegion	What region should this text be displayed in.
	 * @param beginTime		When should the text be displayed.
	 * @param endTime		When should the text stop being displayed.
	 */
	public SmilTextResource(String source, SmilRegion smilRegion, int beginTime, int endTime){
		super(source, smilRegion, beginTime, endTime);
		this.setType(TYPE_TEXT);
		getTextFromSource();
		mTextColor = new Paint();
		updateText();
	}
	
	/**
	 * Loads the text from source into mText
	 */
	private void getTextFromSource(){
		try {
			BufferedReader br = new BufferedReader(new FileReader(new File(SmilResource.ROOT_PATH + super.getSource())));
			mText = "";		//reset text field for consistency.
			String line = br.readLine();
			while(line != null){
				mText += line;
				line = br.readLine();
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
			mText = "Source file not found.";
		} catch (IOException e) {
			e.printStackTrace();
			mText = "Source file not found.";
		}
	}

	/**
	 * Used to prepare text coordinates, so that when text is drawn it is both centered
	 * vertically and horizontally. This is only called once after a call to 
	 * {@link #breakTextToRegion()}.
	 */
	private void prepareText(){
		Rect r = getSmilRegion().getRect();
		if(r.width() > 0 && r.height() > 0){
			mTextColor.setColor(ColorUtils.getComplimentColor(getSmilRegion().getColor()));
			mX = r.centerX();
			int yTop = (int) (r.top + mTextColor.getTextSize() * mTextColor.getTextScaleX());
			mY = (int) (r.centerY() - ((mBreakText.length/2)* mTextColor.getTextSize() * mTextColor.getTextScaleX()));
			if(mY < yTop)
				mY = yTop;	//insure the begining of text is at top of region.
		}
	}
	
	@Override public void play(Canvas canvas) {
		int y = mY;	//need to increment, so dont want to overide.
		
		canvas.save();
		canvas.clipRect(getSmilRegion().getRect());
		
		for(int i = 0; i < mBreakText.length; i ++){
			canvas.drawText(mBreakText[i], mX, y, mTextColor);
			y += mTextColor.getTextSize() * mTextColor.getTextScaleX();
		}
		
		canvas.restore();
	}

	@Override public void stop(Canvas canvas) {
	}
	
	/**
	 * Wraps text for its region. If the region isn't long enough then text will be cut
	 * off once it's hit the end of the region.
	 * @return An array where each index is a line.
	 */
	private String[] breakTextToRegion(){
		mTextColor.setTextAlign(Align.CENTER);		//ensure text will be centered
		Rect r = super.getSmilRegion().getRect();
		if(r.width() > 0 && r.height() > 0){
			//Paint p = super.getSmilRegion().getColor();
			int end = mTextColor.breakText(mText, true, r.width(), null);
			int cutOff;
			String toBreak = mText;
			String returnStr = "";
			String line;
			
			while(end > 0 && end <= toBreak.length()){
				line = toBreak.substring(0, end);
				cutOff = line.lastIndexOf(' ');
				if(cutOff != -1 && end < toBreak.length()){
					end = cutOff;
					line = line.substring(0, cutOff);
					toBreak = toBreak.substring(end + 1);
				}
				else{
					toBreak = toBreak.substring(end);
				}
				
				returnStr += line + "\n";
				end = mTextColor.breakText(toBreak, true, r.width(), null);
			}
			
			return returnStr.split("\n");
		}
		
		return new String[]{""};
	}
	
	/**
	 * Used to update positioning of text if its region size or position has changed.
	 */
	public void updateText(){
		mBreakText = breakTextToRegion();
		prepareText();
	}
}
